package Underworld_Survival;

import javax.xml.transform.stax.StAXSource;
import java.util.*;

import static Underworld_Survival.Game.*;
import static Underworld_Survival.GameOutput.*;

public interface GameEvent {
    void execute(Player player);//玩家参与每一个事件
    String getName();//获取事件名称
}

//全局事件

//1.飞剑偷袭sneakAttackWithFlyingSword_Event
class sneakAttackWithFlyingSword_Event implements GameEvent{
    @Override
    public String getName(){return "【飞剑偷袭】";}

    @Override
    public void execute(Player player){
        GameOutput.println(MsgType.EVENT,"走着走着，突然，不小心踩到这里的一处陷阱。就在那一刹那，数枚飞剑急速想你射来！");
        int hurt=1;
        if(player.getBaseEP()<(int)(stage*0.31+4)){//初始速度4，每3房间加一点速度值
            GameOutput.println(MsgType.EVENT,"可惜自身基础速度欠佳，");
            if(player.getBaseDef()<(int)(stage*0.31+3)){//初始防御4，每4个房间加一点防御值
                GameOutput.println(MsgType.EVENT,"再加上本身防御一般，严重受伤。不过经过了这次历练，自身速度有所提升。");
                player.modifyAttributes(Map.of(AttributeType.BASE_EP,2f),true);
                gameOutput.print(MsgType.STATUS,"当前基础速度："+(player.getBaseEP()-2)+"+2  ");
                hurt=(int)(player.getTotalMaxHP()*0.18);//受到最大生命值的18%伤害
            }else{
                GameOutput.println(MsgType.EVENT,"幸好防御还行，轻微受伤。惊喜的是，速度有了微微提升。");
                player.modifyAttributes(Map.of(AttributeType.BASE_EP,2f),true);
                gameOutput.print(MsgType.STATUS,"当前基础速度："+(player.getBaseEP()-2)+"+2  ");
                hurt=(int)(player.getTotalMaxHP()*0.12);//受到最大生命值的12%伤害
            }
        } else{
            GameOutput.println(MsgType.EVENT,"但是！你凭借着敏捷的反应力，竟躲开了绝大部分飞剑。你整理了下身姿，嘴角上扬。");
            hurt=8;
            gameOutput.print(MsgType.STATUS,"当前基础速度："+player.getBaseEP()+"  ");
        }
        System.out.println();
        player.reduceHP(hurt);
        player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        if(Math.random()<0.3){
            gameOutput.println(MsgType.GET,"你发现了一把完好的飞剑！"+'\n'+"获得武器<飞剑>");
            player.obtainItem(new flyingSword());
        }
    }

}
//2.御守考验testOfTheProtectiveAmulet_Event
class testOfTheProtectiveAmulet_Event implements GameEvent{
    @Override
    public String getName(){
        return "【御守考验】";
    }
    @Override
    public void execute(Player player){
        GameOutput.println(MsgType.EVENT,"进入房间发现什么都没有，正要进入下间房时，发现门上写着“按下按钮，接受重力一击方可开门。”\n" +
                "为了尽快冲破这一间间牢笼，你按下了按钮，同时调动全身，准备受下接下来的一击。一个大锤直向你砸来，无法躲避。");
        int hurt=0;
        if(player.getBaseDef()<(int)(stage*0.32+3)){//初始值为2，每3.3个房间加一点防御值
            gameOutput.println(MsgType.EVENT,"奈何体质堪忧，重重的受了伤。但这次的碰撞中，竟让你的体质得到了强化！");
            player.modifyAttributes(Map.of(AttributeType.BASE_DEF,2f),true);
            gameOutput.print(MsgType.STATUS,"当前基础防御："+(player.getBaseDef()-2)+"+2     ");
            hurt=(int)(player.getTotalMaxHP()*0.18);//受到最大生命值的18%伤害
        }
        else{
            gameOutput.print(MsgType.STATUS,"当前基础防御："+player.getBaseDef()+"     ");
            hurt=(int)(player.getTotalMaxHP()*0.12);//受到最大生命值的12%伤害
        }
        player.reduceHP(hurt);
        player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
    }
}
//3.诡毒迷阵mysteriousAndPoisonousMaze_Event
class mysteriousAndPoisonousMaze_Event implements GameEvent{
    @Override
    public String getName(){return "【诡毒迷阵】";}

    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"一进入这个房间，一股刺鼻的味道直冲天灵盖，不好，是毒！\n"+
                "你迅速做出反应，使用内力减慢血液循环，减慢毒液扩散，并且逼迫毒液排除体外。\n"+
                "一炷香后，你抗了过来，但是受了伤，全身无力。");
        int hurt=(int)(player.getTotalMaxHP()*0.22);//受到最大生命值的22%伤害
        player.reduceHP(hurt);
        player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        if(Math.random()<0.15){
            gameOutput.println(MsgType.GET,"等等，这个房间竟有卷轴！\n你获得了卷轴【剧毒爪秘法】");
            player.obtainItem(new poisonousClaw_SecretTechnique());//获得剧毒爪秘法
        }
    }
}
//4.嗜血祭坛bloodthirstyAltar_Event
class bloodthirstyAltar_Event implements GameEvent{
    @Override
    public String getName(){
        return "【嗜血祭坛】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"房中间有一座刻满符文的石台，中央插着一把匕首，刀柄镶嵌红宝石。"+'\n'+
                "1.献祭：贡献自己最大生命值的30%，让石台赐予我力量！"+'\n'+
                "2.破坏：摧毁祭坛，被诅咒！"+'\n'+"3.无视祭坛，悄然离开"+'\n'+"你的选择是：");
        ShowPlayer.basicProperty();
        int select=inputCheck(1,3);
        if(select==1){
            player.reduceHP((int)(player.getTotalMaxHP()*0.30));
            gameOutput.println(MsgType.INCREASE,"全属性提升！");
            player.modifyAttributes(Map.of(AttributeType.BASE_STR,1f,AttributeType.BASE_DEF,1f,
                    AttributeType.BASE_EP,1f,AttributeType.BASE_MAXAGI,3f),true);
            player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        }else if(select==2){
            gameOutput.println(MsgType.DECREASE,"祭坛被你毁的一片狼藉。你被诅咒，获得buff【诅咒】,能量值降为0\n");
            player.setCurrentAgi(0);
            player.addBuff(new curse());
            gameOutput.println(MsgType.GET,"祭坛爆出"+CurrencyType.GOLD.getDescription()+"100个  "+
                    CurrencyType.DIAMOND.getDescription()+"20个");
            player.rewardGold(100);
            player.rewardDiamond(20);
            player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        }else{
            gameOutput.println(MsgType.EVENT,"什么也没发生");
            player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        }
    }
}
//5.命运轮盘theWheelOfFate_Event
class theWheelOfFate_Event implements GameEvent{
    @Override
    public String getName(){
        return "【命运轮盘】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"生锈的青铜轮盘镶嵌着十二星座浮雕，中心指针滴落水银。\n" +
                "1.转动轮盘：支付10-100"+CurrencyType.GOLD.getDescription()+"转动轮盘，随机属性+3或-3" +
                "（注入"+CurrencyType.GOLD.getDescription()+"越多，增加属性概率越大）\n" +
                "2.注入能量或者血量：随机获得相应数量的"+CurrencyType.GOLD.getDescription()+"或者" +
                CurrencyType.DIAMOND.getDescription());
        gameOutput.println(MsgType.SYSTEM,"你的选择是：");
        ShowPlayer.basicProperty();
        int select=inputCheck(1,2);
        if(select==1) {
            gameOutput.print(MsgType.EVENT,"轮盘的一个小洞渐渐打开，");
            gameOutput.println(MsgType.SYSTEM,"请输入你要注入"+CurrencyType.GOLD.getDescription()+"的数量(10-100)：");
            ShowPlayer.gold();
            int value=inputCheck(10,100);
            if(player.useGold(value)){
                Random random=new Random();
                int randonNumber=random.nextInt(1,4);
                if(randonNumber==1){
                    if(Math.random()<value*0.01){
                        player.modifyAttributes(Map.of(AttributeType.BONUS_STR,3f),true);
                    }else{
                        player.modifyAttributes(Map.of(AttributeType.BONUS_STR,-3f),true);
                    }
                }else if(randonNumber==2){
                    if(Math.random()<value*0.01){
                        player.modifyAttributes(Map.of(AttributeType.BONUS_DEF,3f),true);
                    }else{
                        player.modifyAttributes(Map.of(AttributeType.BONUS_DEF,-3f),true);
                    }
                }else if(randonNumber==3){
                    if(Math.random()<value*0.01){
                        player.modifyAttributes(Map.of(AttributeType.BONUS_EP,3f),true);
                    }else{
                        player.modifyAttributes(Map.of(AttributeType.BONUS_EP,-3f),true);
                    }
                }
            }else{
                gameOutput.println(MsgType.EVENT,"转盘摇了摇头......");
            }
        }
        else{
            gameOutput.println(MsgType.SYSTEM,"你想注入的是？1.血量  2.能量");
            int select1=inputCheck(1,2);
            ShowPlayer.basicProperty();
            if(select1==1){
                Scanner sc=new Scanner(System.in);
                gameOutput.print(MsgType.SYSTEM,"你要献祭多少血？:");
                gameOutput.println(MsgType.DIE,"（温馨提示：别献祭过多导致死亡哦）");
                int value=sc.nextInt();
                player.reduceHP(value);
                if(value>player.getTotalMaxHP()) value=player.getTotalMaxHP();
                if(Math.random()<0.5){//50%获得金币
                    player.rewardGold(value*3);
                    gameOutput.println(MsgType.GET,"获得"+CurrencyType.GOLD.getDescription()+"："+value*3);
                }else{
                    player.rewardDiamond((int)(value*0.5));
                    gameOutput.println(MsgType.GET,"获得"+CurrencyType.DIAMOND.getDescription()+"："+(int)(value*0.5));
                }
            }else{
                Scanner sc=new Scanner(System.in);
                gameOutput.println(MsgType.SYSTEM,"你要献祭多少能量？(最多献祭全部能量)");
                int value=inputCheck(0,player.getCurrentAgi());
                player.reduceAgi(value);
                if(Math.random()<0.5){
                    player.rewardGold(value*4);
                    gameOutput.println(MsgType.GET,"获得"+CurrencyType.GOLD.getDescription()+"："+value*4);
                }else{
                    player.rewardDiamond((int)(value*0.6));
                    gameOutput.println(MsgType.GET,"获得"+CurrencyType.DIAMOND.getDescription()+"："+(int)(value*0.6));
                }
            }
        }
        player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
    }
}
//6.暴君赌桌tyrant_sGamblingTable_Event
class tyrant_sGamblingTable_Event implements GameEvent{
    @Override
    public String getName(){
        return "【暴君赌桌】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"房中间铺着人皮地图的石桌，堆叠着骷髅筹码。\n" +
                "1.赌命：押注最大生命值的30%，猜硬币正反，赢则获得10生命上限，输则扣除押注值\n" +
                "2.掀桌：将引来不满");
        gameOutput.println(MsgType.SYSTEM,"你的选择是：");
        ShowPlayer.basicProperty();
        int select=inputCheck(1,2);
        if(select==1){
            gameOutput.print(MsgType.EVENT,"你拿出赌注  ");
            player.reduceHP((int)(player.getTotalMaxHP()*0.3));
            boolean right=guessTheCoin();
            if(right){
                player.refillHP((int)(player.getTotalMaxHP()*0.3));
                player.modifyAttributes(Map.of(AttributeType.BASE_MAXHP,10f),true);
            }
            player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
        }else if(select==2) {
            gameOutput.println(MsgType.EVENT,"“什么破桌子，还想吓唬我！”你掀翻了桌子!");
            List<Monster> monsters=new ArrayList<>();
            monsters.add(new bone_SkinWeirdPuppet());
            BattleManager battle = new BattleManager(player,monsters);
            monsters.get(0).showPreEntrancePortrayal();
            monsters.get(0).showMonologue();
            battle.startBattle();
        }
    }
}
//7.趣味谜题interestingPuzzle_Event
class interestingPuzzle_Event implements GameEvent{
    @Override
    public String getName(){
        return "【趣味谜题】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"发现了一处玄妙的机关。你凑近一看，居然是一道题！上面写着：\n1+1=?");
        Scanner sc=new Scanner(System.in);
        int answer=sc.nextInt();
        if(answer==2){
            gameOutput.println(MsgType.GET,"你拨动着上面的开关，指着2的位置，机关打开了！里面闪闪发光，竟然是【神秘卷轴】！");
            player.obtainItem(new healthScroll());
        }
        else{
            gameOutput.println(MsgType.EVENT,"你拨动这上面的开关，尝试了一次，他就永久性的锁死了。无奈，你只能离开。");
        }
        player.triggerBuffsInStage(BuffTriggerCondition.STAGE_END);
    }
}
//.堕落圣餐台fallenCommunionTable_Event
class fallenCommunionTable_Event implements GameEvent{
    @Override
    public String getName(){
        return "【堕落圣餐台】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"银质餐盘盛着跳动的心脏与黑色葡萄酒\n" +
                "1. 啜饮圣血（最大生命值-20%，获得【嗜血】buff：造成伤害的40%转化为治疗）\n" +
                "2. 吞食心肉（永久+15生命，但暴击效果降低-5%）  \n" +
                "3. 玷污祭品（获得50"+CurrencyType.GOLD.getDescription()+"，10"+
                CurrencyType.DIAMOND.getDescription()+ "，但下个房间必定遇到怪物）");
        ShowPlayer.basicProperty();
        gameOutput.println(MsgType.SYSTEM,"你的选择是：");
        int select=inputCheck(1,3);
        if(select==1){
            player.reduceHP((int)(player.getTotalMaxHP()*0.2));
            player.addBuff(new bloodthirsty());
        }else if(select==2){
            player.modifyAttributes(Map.of(AttributeType.BASE_MAXHP,15f,
                    AttributeType.BONUS_CRITMULTIPLIER,-0.05f),true);
        }else{
            player.rewardGold(50);
            player.rewardDiamond(10);
            eventManager.setForcedNextEvent(new monsters_Are_Coming());
        }
    }
}
//8.神秘商人mysteriousMerchant_Event
class mysteriousMerchant_Event implements GameEvent{
    @Override
    public String getName(){
        return "【神秘商人】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"正准备走进下一间房间，突然出现了一位神秘商人，询问你是否要买他的神秘物品。" +
                "\n说着，他把他的神秘物品拿了出来：" );
        WeightedRandomSelector<Item> selector = new WeightedRandomSelector<>();//使用权重随机选择器，随机商品
        PeriodConfig<Item> merchantGoods = MerchantConfig.earlyPeriod();//商人随机卖物品（会随机出四至六种）
        List<Item> goods = selector.select(merchantGoods);//用list列表接受随机出来的 4-6 个商品
        for(int i=0;i<goods.size();i++){
            gameOutput.println(MsgType.SHOP,(i+1)+"."+goods.get(i).getName()+" \t"+goods.get(i).getPriceOfPurchase()+
                    " "+goods.get(i).getPurchaseCurrency().getDescription()+ "\t介绍："+goods.get(i).getIntroduction());
        }
        gameOutput.println(MsgType.SHOP,(goods.size()+1)+".垃圾东西，我才不要！");
        gameOutput.println(MsgType.SYSTEM,"请选择你要购买的商品：");
        ShowPlayer.estate();
        int select;
        while(true){
            select=inputCheck(1,goods.size()+1);
            if(select==goods.size()+1) break;
            if(goods.get(select-1).getPurchaseCurrency().equals(CurrencyType.GOLD)){
                if(player.useGold(goods.get(select-1).getPriceOfPurchase())){
                    player.obtainItem(goods.get(select-1));
                }
            }else{
                if(player.useDiamond(goods.get(select-1).getPriceOfPurchase())){
                    player.obtainItem(goods.get(select-1));
                }
            }
        }
    }
}
//9.净化源泉purifyingSpringSource_Event
class purifyingSpringSource_Event implements GameEvent{
    @Override
    public String getName(){
        return "【净化源泉】";
    }
    @Override
    public void execute(Player player){
        gameOutput.println(MsgType.EVENT,"经过了种种磨难，终于可以休息了。\n"+
                "全身被房间灵气包围，血量和能量恢复，负面buff清除。甚至血量上限也突破了！");
        player.modifyAttributes(Map.of(AttributeType.BASE_MAXHP,3f),true);
        player.refillHP((int)(player.getTotalMaxHP()*0.3));
        player.refillAgi((int)(player.getTotalMaxAgi()*0.3));
        player.removeDebuff();
    }
}
//10.路遇小狼encounterALittleWolfOnTheWay_Event
class encounterALittleWolfOnTheWay_Event implements GameEvent{
    @Override
    public String getName(){
        return "【路遇小狼】";
    }
    @Override
    public void execute(Player player){
    }
}
//11.凶狼对峙confrontationWithAFierceWolf_Event
class confrontationWithAFierceWolf_Event implements GameEvent{
    @Override
    public String getName(){
        return "【凶狼对峙】";
    }
    @Override
    public void execute(Player player){
    }
}
//12.水晶蜘蛛crystalSpider_Event
class crystalSpider_Event implements GameEvent{
    @Override
    public String getName(){
        return "【水晶蜘蛛】";
    }
    @Override
    public void execute(Player player){
    }
}
//13.晶甲卫兵crystal_ArmoredGuard_Event
class crystal_ArmoredGuard_Event implements GameEvent{
    @Override
    public String getName(){
        return "【晶甲卫兵】";
    }
    @Override
    public void execute(Player player){
    }
}
//14.boss: 狼人来袭！！！boss_WerewolfAttack_Event
class boss_WerewolfAttack_Event implements GameEvent{
    @Override
    public String getName(){
        return "【boss: 狼人来袭！！！】";
    }
    @Override
    public void execute(Player player){
    }
}
//15.boss:幻影剑士！！！boss_PhantomSwordsman_Event
class boss_PhantomSwordsman_Event implements GameEvent{
    @Override
    public String getName(){
        return "【boss:幻影剑士！！！】";
    }
    @Override
    public void execute(Player player){
    }
}
//16.boss:暗影巫医！！！boss_ShadowWitchDoctor_Event
class boss_ShadowWitchDoctor_Event implements GameEvent{
    @Override
    public String getName(){
        return "【boss:暗影巫医！！！】";
    }
    @Override
    public void execute(Player player){
    }
}
//17.boss:熔岩巨人！！！boss_LavaGiant_Event
class boss_LavaGiant_Event implements GameEvent{
    @Override
    public String getName(){
        return "【boss:熔岩巨人！！！】";
    }
    @Override
    public void execute(Player player){
    }
}
//18.怪物来袭monsters_Are_Coming(用于发生所有普通战斗事件,随机生成一个怪物，与player战斗)
class monsters_Are_Coming implements GameEvent{
    @Override
    public String getName(){
        return "【怪物来袭】";
    }

    @Override
    public void execute(Player player){
        WeightedRandomSelector<Monster > selector = new WeightedRandomSelector<>();//使用权重随机选择器，随机怪物
        List<Monster> monsterList;
        if(stage<=20){//前期
            PeriodConfig<Monster > earlyEvent = MonsterConfig.earlyPeriod();
            monsterList = selector.select(earlyEvent);
        }else if(stage>20&&stage<=40){//中期
            PeriodConfig<Monster > midEvent = MonsterConfig.midPeriod();
            monsterList = selector.select(midEvent);
        }else if(stage>40&&stage<=60){//后期
            PeriodConfig<Monster > lateEvent = MonsterConfig.latePeriod();
            monsterList = selector.select(lateEvent);
        }else{//60关以后，无尽模式
            PeriodConfig<Monster > endlessModeEvent = MonsterConfig.endlessMode();
            monsterList = selector.select(endlessModeEvent);
        }
        BattleManager battle = new BattleManager(player,monsterList);
        monsterList.get(0).showPreEntrancePortrayal();
        monsterList.get(0).showMonologue();
        Monster monster=monsterList.get(0);
        battle.startBattle();
        gameOutput.print(MsgType.GET,"获得奖励：");
        if(monster.getName().equals("小狼")){
            gameOutput.println(MsgType.GET,"[夏日西瓜]");
            player.obtainItem(new summerWatermelon());
        }else if(monster.getName().equals("小骨兵")){
            gameOutput.println(MsgType.GET,"{万能药}");
            player.obtainItem(new panacea());
        }
        else if(monster.getName().equals("凶狼")){
            gameOutput.println(MsgType.GET,"[大肉]");
            player.obtainItem(new largePieceOfMeat());
        }
        else if(monster.getName().equals("水晶蜘蛛")){
            gameOutput.println(MsgType.GET,"[大肉]，[夏日西瓜]");
            player.obtainItem(new summerWatermelon());
            player.obtainItem(new largePieceOfMeat());
        }
        else if(monster.getName().equals("骸皮诡傀")){
            gameOutput.println(MsgType.GET,"[毒蘑菇],"+
                    CurrencyType.GOLD.getDescription()+"50");
            player.obtainItem(new poisonousMushroom());
            player.rewardGold(50);

        }
        else if(monster.getName().equals("晶甲卫兵")){
            gameOutput.println(MsgType.GET,"[夏日西瓜]，"+
                    CurrencyType.DIAMOND.getDescription()+"10");
            player.obtainItem(new summerWatermelon());
            player.rewardDiamond(10);
        }
    }
}
//19.boss来袭boss_Are_Coming(发生boss事件时，生成固定boss,与player战斗)
class boss_Are_Coming implements GameEvent{
    @Override
    public String getName(){
        return "【boss来袭】";
    }
    @Override
    public void execute(Player player){
        List<Monster> monsters=new ArrayList<>();
        if(stage==16){ monsters.add(new boss_Werewolf());//狼人来袭
        }else if(stage==31){ monsters.add(new boss_MirageBlade());//幻影剑士
        }else if(stage==41){ monsters.add(new boss_ShadowHealer());//暗影巫医
        }else if(stage==51){ monsters.add(new boss_MoltenGiant());//熔岩巨人
        }else if(stage==61){ monsters.add(new boss_BoneSoulCommander());//骨魄统领
        }
        BattleManager battle = new BattleManager(player,monsters);
        monsters.get(0).showPreEntrancePortrayal();
        monsters.get(0).showMonologue();
        Monster monster=monsters.get(0);
        battle.startBattle();
        gameOutput.print(MsgType.GET,"击杀boss,获得奖励：");
        if(monster.getName().equals("狼人")){
            gameOutput.println(MsgType.GET,"【血量卷轴】，[大肉]"+
                    CurrencyType.GOLD.getDescription()+"50");
            player.obtainItem(new healthScroll());
            player.obtainItem(new largePieceOfMeat());
            player.rewardGold(50);
        }else if(monster.getName().equals("幻影剑士")){
            gameOutput.println(MsgType.GET,"{仙丹}，{金苹果}，[营养草]，"+
                    CurrencyType.GOLD.getDescription()+"50");
            player.obtainItem(new elixir());
            player.obtainItem(new goldenApple());
            player.obtainItem(new nutritiousGrass());
            player.rewardGold(50);
        }
        else if(monster.getName().equals("暗影巫医")){
            gameOutput.println(MsgType.GET,"[精华草]*2，"+
                    CurrencyType.DIAMOND.getDescription()+"20");
            player.obtainItem(new essenceGrass());
            player.obtainItem(new essenceGrass());
            player.rewardDiamond(20);
        }
        else if(monster.getName().equals("熔岩巨人")){
            gameOutput.println(MsgType.GET,"【万剑归宗秘法】");
            player.obtainItem(new convergenceOfBlades_SecretTechnique());
        }
        else if(monster.getName().equals("骨魄统领")){
        }
    }
}

